package org.pwwong.fxscalautils


import com.sun.scenario.scenegraph.{ JSGPanel,
                                     SGNode }

import com.sun.scenario.scenegraph.fx.{FXGroup, FXText}

import javax.swing.{ JFrame, 
                     SwingUtilities }

import java.awt.{ GraphicsEnvironment,
                  GraphicsDevice,
                  Dimension}
import java.awt.event.{ ComponentAdapter,
                        ComponentEvent }


import org.pwwong.fxscalautils.Predef._
import org.pwwong.fxscalautils.components.Component
import org.pwwong.fxscalautils.components.containers._
import org.pwwong.scalautils.property._
import org.pwwong.scalautils.event._
import org.pwwong.scalautils.signals.ConstantSignal
import org.pwwong.scalautils.signals.Predef._


object DisplayMode extends Enumeration {
  val Windowed, Fullscreen, FullscreenForced = Value
}

abstract class FXScalaApp(_initX:Int, _initY:Int, val displayMode:DisplayMode.Value) extends Canvas with AccessibleChildren with Runnable { outer: FXScalaApp =>
  private val _jframe:JFrame = new JFrame
  private val _jsgPanel:JSGPanel = new JSGPanel
  
  private val _childLayer = new Canvas with AccessibleChildren
  
  _containerLevel <= 0
  _width <= ConstantSignal[Double](_initX.asInstanceOf[Double])
  _height <= ConstantSignal[Double](_initY.asInstanceOf[Double])
    
  setChildren(
    _childLayer w(100 %%) h(100 %%)
    //DragManager.DragLayer w(100 %%) h(100 %%)
  )
  
  private var hasStart:Boolean = false
  
  override def contents(comps:Component*):outer.type = { 
    _childLayer.contents(comps:_*); 
    if(!hasStart){
      LayoutManager.start
      hasStart = true
    }
    outer 
  }
  
  override def run(){
    initGUI
    initDisplay
    initListeners
    resizeToJFrame
  }
  
  protected def resizeToJFrame {
    _width <= _jframe.getWidth.toDouble
    _height <= _jframe.getHeight.toDouble
  }
  
  protected def initListeners {
    _jframe.addComponentListener(
      new ComponentAdapter { override def componentResized(e:ComponentEvent){ outer.resizeToJFrame } }
    )
  }
  
  private def initGUI {
    _jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	_jframe.add(_jsgPanel);
    _jsgPanel.setScene(compNodeImpl)
  }
  
  private def initDisplay {
    val device:GraphicsDevice = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice()
    
	 // Set DisplayMode
	displayMode match {
	case DisplayMode.Windowed => _jframe.setSize(new Dimension(_initX, _initY))
	case DisplayMode.Fullscreen =>
		if (device.isFullScreenSupported()) {
			try { device.setFullScreenWindow(_jframe) } finally {	device.setFullScreenWindow(null) }
			if (device.isDisplayChangeSupported)
				device.setDisplayMode( new java.awt.DisplayMode(1680, 1050, 32, 60) )
	        else
				println("Change display mode not supported")
		} 
	case DisplayMode.FullscreenForced => { _jframe.setUndecorated(true); device.setFullScreenWindow(_jframe) }
	}
	
	_jframe.invalidate
    _jframe.setVisible(true)
  }
  
  def main(args : Array[String]){
    SwingUtilities.invokeLater(this)
  }
}
